package com.jingyuyao.tactical;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeFontParameter;
import com.badlogic.gdx.utils.Array;

public class DynamicBitmapFont extends BitmapFont {

    private FreeTypeFontGenerator globalGenerator;

    public DynamicBitmapFont(FreeTypeFontParameter param) {
        globalGenerator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/MapleMono-SC-NF-Regular.ttf"));

        param.incremental = true;
        param.characters = "howdY\u0000";

        FreeTypeFontGenerator.setMaxTextureSize(128);
        FreeTypeFontGenerator.FreeTypeBitmapFontData data = new FreeTypeFontGenerator.FreeTypeBitmapFontData() {
            public int getWrapIndex(Array<Glyph> glyphs, int start) {
                return SimplifiedChinese.getWrapIndex(glyphs, start);
            }
        };

        // By default latin chars are used for x and cap height, causing some fonts to display non-latin chars out of bounds.
        data.xChars = new char[]{'动'};
        data.capChars = new char[]{'动'};

        BitmapFont bitmapFont = globalGenerator.generateFont(param, data);
    }

    public void dispose() {
        FreeTypeFontGenerator.setMaxTextureSize(1024);
    }

    public static class SimplifiedChinese {
        public static int getWrapIndex(Array<Glyph> glyphs, int start) {
            int i = start - 1;
            for (; i >= 1; i--) {
                int startChar = glyphs.get(i).id;
                if (!SimplifiedChinese.legalAtStart(startChar)) continue;
                int endChar = glyphs.get(i - 1).id;
                if (!SimplifiedChinese.legalAtEnd(endChar)) continue;
                // Don't wrap between ASCII chars.
                if (startChar < 127 && endChar < 127 && !Character.isWhitespace(startChar)) continue;
                return i;
            }
            return start;
        }

        static private boolean legalAtStart(int ch) {
            return switch (ch) {
                case '!', '%', ')', ',', '.', ':', ';', '>', '?', ']', '}', '¢', '¨', '°', '·', 'ˇ', 'ˉ', '―', '‖', '’', '”', '„', '‟', '†', '‡', '›', '℃', '∶', '、', '。', '〃', '〆', '〈', '《', '「', '『', '〕', '〗', '〞', '﹘', '﹚', '﹜', '！', '＂', '％', '＇', '）', '，', '．', '：', '；', '？', '］', '｀', '｜', '｝', '～' ->
                        false;
                default -> true;
            };
        }

        static private boolean legalAtEnd(int ch) {
            return switch (ch) {
                case '$', '(', '*', ',', '£', '¥', '·', '‘', '“', '〈', '《', '「', '『', '【', '〔', '〖', '〝', '﹗', '﹙', '﹛', '＄', '（', '．', '［', '｛', '￡', '￥' ->
                        false;
                default -> true;
            };
        }
    }
}
